#pragma once

#include "../../../Libs/headers.default.h"
#include "../../../Libs/headers.classification.h"

using namespace loirey;

namespace twenty_news_group
{

	class CVocabulary
	{
	public:
		typedef map<string, int> CTermMap;
	public:
		int TermAmount;
		CSimpleTypeArray<string> TermList;
		CTermMap TermMap;

	public:
		void LoadFromFile(string strFN_Vocabulary);
		void SaveToFile(string strFN_Vocabulary) const;
	public:
		CVocabulary();
		void Clear();
	public:
		int GetTermOriginalIndex(string strTerm) const;
	};

	class CSelectedVocabulary
	{
	public:
		const CVocabulary* pVocabulary;
	public:
		int SelectedAmount;
		CSimpleTypeArray<int> TermSelectedFlagList;
		CSimpleTypeArray<int> SelectedTermIndexList;

	public:
		void InitVocabulary(const CVocabulary* pVocabulary);
	public:
		void LoadFromFile(string strFN_VocabularySelection);
		void SaveToFile(string strFN_VocabularySelection) const;
	public:
		void MakeSelectedList();
	};

	class CTermOccurrence
	{
	public:
		int TermIndex;
		int Amount;

	public:
		CTermOccurrence();
		CTermOccurrence(int TermIndex, int Amount);
		bool operator < (const CTermOccurrence& Another) const;
	};

	class CDiscreteDocument
	{
	public:
		int DocumentLabel;
		int DocumentIndex;
		int TermKindAmount;
		int TermTotalAmount;
		CSimpleTypeArray<CTermOccurrence> TermOccurrenceList;

	public:
		void Clear();
		void NewTerm(int TermIndex, int Amount);
		void SortAndUnique();
	public:
		bool operator < (const CDiscreteDocument& Another) const;
	public:
		int GetTermOccurrenceAmount(int TermIndex) const;
	};

	class CDenseDocument
	{
	public:
		int DocumentLabel;
		int DocumentIndex;
		CSimpleTypeArray<int> PerTermCountList;
	};

	class CDocumentList : public CLabeledDataSetForClassification
	{
	public:
		const CVocabulary* pVocabulary;
		CSelectedVocabulary* pSelectedVocabulary;
		const double* pIDF;
	public:
		int DocumentAmount;
		CSimpleTypeArray<CDiscreteDocument> DocumentList;

	public:
		CDocumentList();
		void InitVocabulary(const CVocabulary* pVocabulary);
		void InitSelectedVocabulary(CSelectedVocabulary* pSelectedVocabulary);
		void InitIDF(const double* pIDF);
	public:
		void InitDocumentList(string strFN_Data, string strFN_Label);
	public:
		double ComputeIDF(CSimpleTypeArray<double>& IDF_List);
		double ComputeIDF(CSimpleTypeArray<double>& IDF_List, const CWeightedClassificationExampleList& DocumentList);
	public:
		void DoFeatureSelection(
			CSelectedVocabulary& DstSelectVocabularyList, CSimpleTypeArray<double>& Dst_IDF_List,
			int DF_Threshold);
		void DoFeatureSelection(
			CSelectedVocabulary& DstSelectVocabularyList, CSimpleTypeArray<double>& Dst_IDF_List,
			int DF_Threshold, const CWeightedClassificationExampleList& SelectedDocumentList);
	public:
		//static void Save_IDF_List(string strFN_IDF_List) const;
		//static void Load_IDF_List(string strFN_IDF_List);
	public:
		virtual int GetExampleAmount();
		virtual double GetExampleInitialWeight(int ExampleIndex);
		virtual int GetFeatureDimension();
		virtual double GetExampleFeature(int ExampleIndex, int FeatureIndex);
	public:
		virtual int GetExampleLabel(int ExampleIndex);
	public:
		virtual double GetDataDensity();
		virtual void MakeSparseVector_ByExample(CSparseVector& DstFeatureVector, int SrcExampleIndex);
	};

	class CTargetBinaryLabelSets
	{
	public:
		CDataSetForBinaryClassification BinaryClassificationDataSetPrototype;

	public:
		void myInit(string strFN_LabelSettings);
	};

};

using namespace twenty_news_group;

